package msg

import (
	"errors"
	"fmt"
	"sync"
)

type PlayerReady struct {
	Userid string
}

type ChuPai struct {
	Userid string
	Cards  []string
}

type AllPlayers struct {
	players    map[string]*Player
	playerlock sync.RWMutex
}

var aps *AllPlayers
var apslock sync.Mutex

func GetAllPlayers() *AllPlayers {
	apslock.Lock()
	defer apslock.Unlock()
	if aps == nil {
		aps = new(AllPlayers)
		aps.players = make(map[string]*Player)
	}
	return aps
}

func (a *AllPlayers) UserLogin(uid string) error {
	a.playerlock.RLock()
	_, ok := a.players[uid]
	if !ok {
		a.playerlock.RUnlock()
		return errors.New("用户已存在")
	}
	a.playerlock.RUnlock()
	p1 := new(Player)
	p1.UserId = uid
	a.playerlock.Lock()
	a.players[uid] = p1
	a.playerlock.Unlock()
	return nil
}

func (a *AllPlayers) GetExistUser(uid string) (*Player, error) {
	a.playerlock.RLock()
	p, ok := a.players[uid]
	a.playerlock.RUnlock()
	if ok {
		return p, nil
	}
	return nil, errors.New("用户不存在")
}

type Player struct {
	UserId string
	//手牌
	Cards []Card
	//出牌和顺序
	OutCards [][]Card
	//准备好开始
	ReadyStart bool
	RoomId     string
	Room       *Room
	playerLock sync.Mutex
}

func (p *Player) Ready() {
	p.playerLock.Lock()
	if !p.ReadyStart && p.RoomId != "" {
		p.ReadyStart = true
	}
	p.playerLock.Unlock()
}

func (p *Player) Chupai(cs []Card) error {
	var err error
	if p.Room.Players[p.Room.NextPlayer].UserId != p.UserId {
		return errors.New("没轮到你出牌！")
	}
	tmp := make(map[string]Card)
	for _, o := range p.Cards {
		tmp[o.ToString()] = o
	}
	for _, o := range cs {
		s := o.ToString()
		_, ok := tmp[s]
		if !ok {
			return errors.New("你没有这张牌！")
		}
		delete(tmp, s)
	}
	if p.Room.PassBec < 3 && p.Room.Players[p.Room.PassBec].UserId != p.UserId {
		err = p.Room.CalCards(cs)
		if err != nil {
			return err
		}
	}
	p.Room.BeforeChupai = cs
	p.OutCards = append(p.OutCards, cs)
	p.Cards = make([]Card, 0, 0)
	for _, v := range tmp {
		p.Cards = append(p.Cards, v)
	}
	p.Room.PassBec = 99
	p.Room.NextPlayer++
	if p.Room.NextPlayer == 3 {
		p.Room.NextPlayer = 0
	}
	return nil
}

func (p *Player) Pass() {
	if p.Room.PassBec == 99 {
		b := p.Room.NextPlayer - 1
		if b < 0 {
			p.Room.PassBec = 2
		} else {
			p.Room.PassBec = b
		}
	}
	p.Room.NextPlayer++
	if p.Room.NextPlayer == 3 {
		p.Room.NextPlayer = 0
	}
	p.Room.BeforeChupai = []Card{}
}

func (p *Player) Win() {
	fmt.Println(fmt.Sprintf("%s说：我赢了！"))
	p.Room.IsStart = false
}

func (p *Player) ShowCards() []Card {
	cs := p.Cards
	for i := 0; i < len(cs); i++ {
		for j := 0; j < len(cs)-i-1; j++ {
			if cs[j].Num > cs[j+1].Num {
				cs[j], cs[j+1] = cs[j+1], cs[j]
			}
		}
	}
	return cs
}
